Exportar datos a excell

Hola

En estos dias he estado tratando de exportar unos datos a csv pero tengo
un problema es demasiada información y habeces se queda mucho tiempo y
nunca exporta, otra es que muchas veces el mongrel muere y el mensaje es
que ha terminado por una causa desconocida.

Como puedo hacer para que no se cuelgue el servidor y para que la
exportación sea mas ligera.

Gracias

Podrías pegar [1] el código que tienes para poder ayudarte?

1- http://pastie.org/

2009/6/23 Jhony A. [email protected]:

¿Cuánto le cuesta ejecutar cada consulta? Si el problema no es el tiempo
de ejecución de las consultas yo probaría a usar FasterCSV en vez de
CSV::Writer porque me da a mi que CSV::Writer es lentillo(de ahí el
nombre de la gema).

Suerte

Jhony A. wrote:

En el controlador tengo esto
JOIN PROJECTS P
LEFT JOIN CUSTOM_VALUES F
end
:type => ‘text/csv; header=present’, :filename => ‘export.csv’) }
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
AND i.project_id = #{issue[‘id’]}
total=(total.to_f).round(2)

                   "T.Estimado",
    fields = [issue['actividad'],
                issue['comentario'],
               "",
              ""]

Gracias por cualquier ayuda


Rafa

Ceritium wrote:

Podr�as pegar [1] el c�digo que tienes para poder ayudarte?

1- http://pastie.org/

2009/6/23 Jhony A. [email protected]:

En el controlador tengo esto

el sql

sql=“SELECT
p.name’project’,i.project_id’id’,i.id’tid’,i.id’tarea_id’,concat(firstname,’
‘,lastname)‘nombre’,subject’actividad’,g.NOMBRE
‘gerencia’,c.value’aplicacion’,f.value’planeada’,I.CCOSTOS’ccosto’,estimated_hours
‘Estimado’,hours’Dedicado’,spent_on’freporte’,comments’comentario’,done_ratio’ejecucion’,e.name’facturable’,i.due_date’termina’,i.start_date’comienza’,it.name’estado’
FROM TIME_ENTRIES T LEFT JOIN ISSUES I
ON T.ISSUE_ID=I.ID,
JOIN ISSUE_STATUSES IT
ON IT.ID=I.STATUS_ID
JOIN PROJECTS P
ON T.PROJECT_ID=P.ID
LEFT JOIN GERENCIAS G
ON I.GERENCIA_ID=G.ID
JOIN ENUMERATIONS E
ON E.ID=T.ACTIVITY_ID
JOIN USERS U
ON T.USER_ID=U.ID
LEFT JOIN CUSTOM_VALUES C
ON T.ISSUE_ID=C.CUSTOMIZED_ID
AND C.CUSTOM_FIELD_ID=43
LEFT JOIN CUSTOM_VALUES F
ON T.ISSUE_ID=F.CUSTOMIZED_ID
AND F.CUSTOM_FIELD_ID=40 "
sql << " WHERE I.PROJECT_ID in (#{@projects.join(‘,’)})
AND T.USER_ID in (#{@users.join(‘,’)})”
sql <<" AND T.SPENT_ON >= (‘%s’)" % @date_from
sql <<" AND T.SPENT_ON <= (‘%s’)" % @date_to
sql <<" AND i.status_id in (#{@issues_status.join(‘,’)})"
sql << " AND t.activity_id in (#{@activities.join(‘,’)})"
if @gerencia != “”
sql << " AND g.id = %s"%@gerencia
end
if @aplicacion[0] != ‘-1’
sql << " AND c.value = (‘%s’)“%@aplicacion
end
sql<<” order by 2,5,13"

  @issues = ActiveRecord::Base.connection.select_all(sql)

El metodo para exportar a csv

respond_to do |format|
    format.csv  { 

send_data(issues_to_csv(@issues,@users,@date_from,@date_to,@activities,@estimado,@totalf).read,
:type => ‘text/csv; header=present’, :filename => ‘export.csv’) }
end

#En el helper tengo esto.

def issues_to_csv(issues,users,from,to,activities,estimado,totalf)
@projects=“”
ic = Iconv.new(l(:general_csv_encoding), ‘UTF-8’)
decimal_separator = l(:general_csv_decimal_separator)
export = StringIO.new
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|

  issues.each do |issue|

  # Por cada  proyecto debo sumar unas horas estimadas.
  if issue['id'] != @projects
    csv << ''
    sql="SELECT sum(hours)'hours'
      FROM time_entries t, issues i
      WHERE i.id=t.issue_id
      AND t.user_id in (#{users.join(',')})
      AND i.project_id = #{issue['id']}
      AND t.activity_id in (#{activities.join(',')})
      AND t.spent_on >= ('#{from}')
      AND t.spent_on <= ('#{to}')
        GROUP BY i.project_id"
     total=0
          @total = ActiveRecord::Base.connection.select_all(sql)
          @total.each do |z|
            total = z['hours'].to_f
          end

    total=(total.to_f).round(2)

    @projects=issue['id']
    projects = [issue['project'],
                   total,
                   l(:field_hours)
                   ]
    csv << projects.collect {|c| begin; ic.iconv(c.to_s); rescue; 

c.to_s; end }
csv << ‘’
end

  # cabeceras.

  headers = [ l(:field_subject),
                   "F.Inicio",
                   "F.Fin",
                   l(:field_status),
                   l(:informe_gerencia_label),
                   l(:informe_aplicacion_label),
                   "C.C",
                   "Planeada",
                   "T.Estimado",
                   "T.Dedicado",
                   "F.Reporte",
                   "Detalle",
                   "Facturable",
                   l(:field_assigned_to),
              ]

  csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; 

c.to_s; end }
#tareas
fields = [issue[‘actividad’],
issue[‘comienza’],
issue[‘termina’],
issue[‘estado’],
issue[‘gerencia’],
issue[‘aplicacion’],
issue[‘ccosto’],
issue[‘planeada’],
issue[‘Estimado’],
issue[‘Dedicado’],
issue[‘freporte’],
issue[‘comentario’],
issue[‘facturable’],
issue[‘nombre’]
]

    csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; 

c.to_s; end }

  end
  totales=["",
               "",
               "",
               "",
               "",
               "",
               "",
               "",
              estimado,
              totalf,
              "",
              "",
              "",
              ""]
    csv << totales.collect {|c| begin; ic.iconv(c.to_s); rescue; 

c.to_s; end }
end
export.rewind
export
end

En el momento se estan recibiendo desde las bd 20.000 registros y esto
tiende a aumentar

Gracias por cualquier ayuda

Excel o CSV? para excel mirate http://spreadsheet.rubyforge.org/

Yo lo utilizo en varios proyectos y me va muy bien.

Para CSV FasterCSV, como te han recomendado, también está muy bien.

Otra recomendación, no cargues tanto los controladores, mete todo lo que
puedas en los modelos, clases propias y módulos y en los controladores
utiliza respond_to

def show
@issue = Issue.find…
respond_to do |format|
format.html
format.xml {…}
format.csv { @issue.to_csv } # el to_csv lo tendrías que implementar
format.xls { @issue.to_xls } # o algo como MyXLSClass.export(@issue)
format.pdf { @issue.to_pdf } #
format.png { @issue.to_png } #
end
end

sds

Jorge

Hola estuve haciendo pruebas de performance con fastercsv y la
exportacion de 36131 filas se demoro 1 minuto con 40 segundos.

Mejoro mucho el tiempo de respuesta y el servidor no se muere.

Muchas gracias por todo

Otra pregunta
esto esta en el metodo de exportacion
ic = Iconv.new(‘ISO-8859-15’, ‘UTF-8’)
decimal_separator = l(:general_csv_decimal_separator)
export = FasterCSV.generate(:col_sep => l(:general_csv_separator))
do |csv|

y muchos de los datos que son exportados tienen tilde, el problema es
que muchos de estos quedan con la tilde bien pero otros quedan con los
caracteres rraros pero yo pensaba que con iconv este error no volveria a
pasar pero esto ya fue algo demasiado raro que formateara algunos datos
y otros no

Muchas gracias por toda la ayuda que me han dado hacerca del tema.

Rafael García wrote:

¿Cuánto le cuesta ejecutar cada consulta? Si el problema no es el tiempo
de ejecución de las consultas yo probaría a usar FasterCSV en vez de
CSV::Writer porque me da a mi que CSV::Writer es lentillo(de ahí el
nombre de la gema).

Suerte

Jhony A. wrote:

En el controlador tengo esto
JOIN PROJECTS P
LEFT JOIN CUSTOM_VALUES F
end
:type => ‘text/csv; header=present’, :filename => ‘export.csv’) }
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
AND i.project_id = #{issue[‘id’]}
total=(total.to_f).round(2)

                   "T.Estimado",
    fields = [issue['actividad'],
                issue['comentario'],
               "",
              ""]

Gracias por cualquier ayuda

Gracias por la respuesta,

Tienen algun ejemplo sencillo de como utilizar fastercsv

Gracias


Rafa

Jhony A. wrote:

Tienen algun ejemplo sencillo de como utilizar fastercsv

http://fastercsv.rubyforge.org/classes/FasterCSV.html